package com.api.model;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.component.domain.Content;
import com.component.domain.MChannel;
import com.component.domain.MModel;
import com.component.enumitem.ModelSumTypeEnum;
import com.component.service.ContentService;
import com.component.service.MChannelService;
import com.component.service.MModelService;
import com.system.common.Result;
import com.system.util.EnumToListConverter;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.HashMap;
import java.util.Map;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Classname ModeViewApi
 * @Description TODO
 * @Date 2023/10/24 15:07
 * @Created by XiongXiong
 * @Author: X.I.O
 *
 * 数据视图汇总
 */
@RestController
@RequestMapping("modeview")
public class ModeViewApi {

    @Autowired
    private MChannelService mChannelService;

    @Autowired
    private MModelService mModelService;

    @Autowired
    private ContentService contentService;

    @GetMapping("getmodelsumtype")
    public JSONObject getModelSumType(){
        ModelSumTypeEnum[] model=ModelSumTypeEnum.values();
        List<Map<String,Object>> mapList=EnumToListConverter.convert(model,"type","typeName");
        return Result.successInfo(mapList);
    }

    /**
     * 获取栏目汇总数据
     * @param channelId
     * @return
     */
    @GetMapping("getbyid")
    public JSONObject getModeViewApi(@RequestParam("channelId")String channelId) {
        MChannel mChannel=mChannelService.getById(channelId);
        if(mChannel==null){
            return Result.errorInfo("栏目不存在");
        }
        if(!StringUtils.isNotBlank(mChannel.getModelId())){
            return Result.errorInfo("未设置模型id");
        }
        MModel mModel=mModelService.getById(mChannel.getModelId());
        if(mModel == null){
            return Result.errorInfo("设置的模型不存在, 请重新在试");
        }
        List<String> list=mModelService.getSumTableFieldsByModel(mModel);
        if(list==null || list.size() == 0){
            return Result.errorInfo("未设置统计字段");
        }
        SimpleDateFormat dft=null;
        String datetype=mModel.getSumtype();
        if("month".equals(datetype)){
            dft = new SimpleDateFormat("yyyy-MM");
        }else if("day".equals(datetype)) {
            dft=new SimpleDateFormat("yyyy-MM-dd");
        }else if("year".equals(datetype)){
            dft = new SimpleDateFormat("yyyy");
        }else {
            dft=new SimpleDateFormat("yyyy-MM-dd");
        }
        List<Map<String,String>> labels=mModelService.getTableLabelByModel(mModel);
        Map<String,String> maps=labels.stream().collect(Collectors.toMap((e)->e.get("field"), (e)->e.get("fieldName"), (key1, key2) -> key2));
        List<Content> contents=contentService.sumContent(mChannel.getId().toString());
        List<Map<String,String>> fields=new ArrayList<>();
        //获取到列
        List<Map<String,Object>> datas=new ArrayList<>();
        Map<String,String> dateField=new HashMap<>();
        dateField.put("key","date");
        dateField.put("value","日期");
        fields.add(dateField);
        for (String str:list){
            String fieldName=maps.get(str);
            Map<String,String> field=new HashMap<>();
            field.put("key",str);
            field.put("value",fieldName);
            fields.add(field);
        }
        Map<String,Map<String,Double>> mapObjects=new HashMap<>();
        for (int i = 0; i < contents.size(); i++) {
            try {
                Map<String,Double> doubleMap=createMapDouble(list);
                Content content = contents.get(i);
                Date date=content.getCreatetime();
                String dateStr=dft.format(date);
                JSONObject obj=JSONObject.parseObject(content.getContent());
                if(obj.containsKey("array")){
                    JSONArray array=obj.getJSONArray("array");
                    if(array!=null && array.size() > 0){
                        for(Object arr : array){
                            JSONObject json=(JSONObject) arr;
                            doubleMap.forEach((k,v)->{
                                if(json.containsKey(k)){
                                    Double val=getDouble(json,k)+v;
                                    doubleMap.put(k, val);
                                }
                            });
                        }
                    }
                }
                if(mapObjects.containsKey(dateStr)){
                    Map<String,Double> map=mapObjects.get(dateStr);
                    map.forEach((k,v)->{
                        if(doubleMap.containsKey(k)){
                            Double val = doubleMap.get(k)+v;
                            map.put(k, val);
                        }
                    });
                }else {
                    mapObjects.put(dateStr,doubleMap);
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        //转换成数据列表
        mapObjects.forEach((k,v)->{
            Map<String,Object> o=mapDoubleToMap(v);
            o.put("date",k);
            datas.add(o);
        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data",datas);
        jsonObject.put("fields",fields);
        return Result.successInfo(jsonObject);
    }

    public Map<String,Object> mapDoubleToMap(Map<String,Double> data){
        Map<String, Object> map = new HashMap<>();
        data.forEach((k,v)->{
            map.put(k, v);
        });
        return map;
    }

    public Double getDouble(JSONObject json,String field){
        Double value=0.0;
        try {
            value=json.getDouble(field);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    public Map<String,Double> createMapDouble(List<String> strs){
        Map<String, Double> map = new HashMap<>();
        for (String str : strs) {
            map.put(str,0.0);
        }
        return map;
    }


    public static void main(String[] args) {
        // 定义公式字符串
        String formulaStr = "(ab*b)+c-c*(ab+b)";

        // 定义字段数据 map
        Map<String, Object> data = new HashMap<>();
        data.put("ab", 1);
        data.put("b", 2);
        data.put("c", 3);

        // 获取一个脚本引擎
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");

        try {
            // 设置字段数据为脚本引擎的上下文变量
            data.forEach((k,v)->{
                engine.put(k,v);
            });

            // 执行公式字符串，得到计算结果
            Object result = engine.eval(formulaStr);

            System.out.println(result); // 输出 6
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

}
